﻿using RMS.Common;
using RMS.EF.Model;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using System.Threading.Tasks;

namespace RMS.BLL
{
    public class MenuBll
    {

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="model">新增的模型实体</param>
        /// <returns></returns>
        public CommonOutPutVm Add(RMS_Menu model)
        {
            var result = new CommonOutPutVm();
            #region 输入验证
            var errdic = model.Validate();
            if (errdic != null)
            {
                result.ErrorDic = errdic;
                return result;
            }
            #endregion
            #region 默认值赋值
            var now = DateTime.Now;
            model.Id = Guid.NewGuid().ToString();
            model.EDeleted = E_Deleted.Normal;
            model.CreationTime = now;
            model.CreationUser = model.LastUpdateUser;
            model.LastUpdateTime = now;
            #endregion
            using (var db = new RMSEntities())
            {
                using (var tran = db.Database.BeginTransaction())
                {
                    try
                    {
                        #region 存在验证
                        bool exist = db.RMS_Menu.Any(p => p.Deleted == (int)E_Deleted.Normal && p.Id != model.Id
                            && p.ProgramId == model.ProgramId && p.ParentId == model.ParentId && p.Url == model.Url && !string.IsNullOrEmpty(p.Url));
                        if (exist)
                        {
                            result.Message = "菜单已经存在";
                            return result;
                        }
                        #endregion
                        #region 保存
                        db.RMS_Menu.Add(model);
                        int row = db.SaveChanges();
                        if (row != 1)
                        {
                            result.Message = "新增菜单保存异常：" + model.Id;
                            return result;
                        }
                        #endregion
                        #region 批量起用
                        if (model.Status == (int)E_Status.Enable)
                        {
                            result = EnableSon(model.ParentId, db);
                            if (!result.IsSuccess)
                            {
                                tran.Rollback();
                                result.Message = "修改失败";
                                return result;
                            }
                        }
                        #endregion
                        tran.Commit();
                    }
                    catch (Exception e)
                    {
                        tran.Rollback();
                        throw e;
                    }
                }
            }
            result.IsSuccess = true;
            result.Message = "保存成功";
            return result;
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="model">修改后的模型实体</param>
        /// <returns></returns>
        public CommonOutPutVm Updata(RMS_Menu model)
        {
            var result = new CommonOutPutVm();
            #region 输入验证
            var errdic = model.Validate();
            if (errdic != null)
            {
                result.ErrorDic = errdic;
                return result;
            }
            #endregion
            #region 默认值赋值
            model.LastUpdateTime = DateTime.Now;
            #endregion
            using (var db = new RMSEntities())
            {
                using (var tran = db.Database.BeginTransaction())
                {
                    try
                    {
                        #region 存在验证
                        bool exist = db.RMS_Menu.Any(p => p.Deleted == (int)E_Deleted.Normal && p.Id != model.Id
                            && p.ProgramId == model.ProgramId && p.ParentId == model.ParentId && p.Url == model.Url && !string.IsNullOrEmpty(p.Url));
                        if (exist)
                        {
                            result.Message = "菜单已经存在";
                            return result;
                        }
                        #endregion
                        #region 保存
                        db.Entry(model).State = EntityState.Modified;
                        db.Entry(model).Property(p => p.Deleted).IsModified = false;
                        db.Entry(model).Property(p => p.CreationTime).IsModified = false;
                        db.Entry(model).Property(p => p.CreationUser).IsModified = false;
                        int row = db.SaveChanges();
                        if (row != 1)
                        {
                            tran.Rollback();
                            result.Message = "修改菜单保存异常：" + model.Id;
                            return result;
                        }
                        #endregion
                        #region 批量起用
                        if (model.Status == (int)E_Status.Enable)
                        {
                            result = EnableSon(model.ParentId, db);
                            if (!result.IsSuccess)
                            {
                                tran.Rollback();
                                result.Message = "修改失败";
                                return result;
                            }
                        }
                        #endregion
                        #region 批量禁用
                        if (model.Status == (int)E_Status.Disable)
                        {
                            result = DisableSon(model.Id, db);
                            if (!result.IsSuccess)
                            {
                                tran.Rollback();
                                result.Message = "修改失败";
                                return result;
                            }
                        }
                        #endregion
                        tran.Commit();
                    }
                    catch (Exception e)
                    {
                        tran.Rollback();
                        throw e;
                    }
                }
            }
            result.IsSuccess = true;
            result.Message = "保存成功";
            return result;
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="searchModel">筛选条件</param>
        /// <returns></returns>
        public CommonOutPutVm GetBySearch(S_RMS_Menu searchModel)
        {
            var result = new CommonOutPutVm();
            using (var db = new RMSEntities())
            {
                var q = db.RMS_Menu.Where(p => p.Deleted == (int)E_Deleted.Normal);
                #region where
                if (!string.IsNullOrWhiteSpace(searchModel.SearchValue))
                {
                    q = q.Where(p => p.Name.Contains(searchModel.SearchValue) || p.Url.Contains(searchModel.SearchValue));
                }
                if (searchModel.Status != E_Status.All)
                {
                    q = q.Where(p => p.Status == (int)searchModel.Status);
                }
                if (searchModel.Type_M != E_Type_Menu.All)
                {
                    q = q.Where(p => p.Type == (int)searchModel.Type_M);
                }
                if (!string.IsNullOrWhiteSpace(searchModel.ProgramId))
                {
                    q = q.Where(p => p.ProgramId == searchModel.ProgramId);
                }
                #endregion
                #region order by
                q = q.OrderBy(p => p.Ordering);
                #endregion
                var data = q.ToList();
                result.Data = data;
            }
            result.IsSuccess = true;
            return result;
        }
        /// <summary>
        /// 软删除
        /// </summary>
        /// <param name="id">数据Id字符串","分隔</param>
        /// <returns></returns>
        public CommonOutPutVm Delete(string id)
        {
            CommonOutPutVm result = new CommonOutPutVm();
            using (var db = new RMSEntities())
            {
                using (var tran = db.Database.BeginTransaction())
                {
                    try
                    {
                        db.Database.ExecuteSqlCommand("update RMS_Menu set Deleted=1 where Id in ('" + id + "')");
                        db.SaveChanges();
                        result = DeleteSon(id, db);
                        if (!result.IsSuccess)
                        {
                            tran.Rollback();
                            result.Message = "删除失败";
                            return result;
                        }
                        tran.Commit();
                    }
                    catch (Exception e)
                    {
                        tran.Rollback();
                        throw e;
                    }
                }
            }
            result.IsSuccess = true;
            result.Message = "删除成功";
            return result;
        }
        /// <summary>
        /// 根据Id获取未删除的实体
        /// </summary>
        /// <param name="id">Id主键</param>
        /// <returns></returns>
        public CommonOutPutVm GetById(string id)
        {
            var result = new CommonOutPutVm();
            using (var db = new RMSEntities())
            {
                var data = db.RMS_Menu.AsNoTracking().FirstOrDefault(p => p.Id == id && p.Deleted == (int)E_Deleted.Normal);
                if (data == null)
                {
                    result.Message = "菜单不存在";
                    return result;
                }
                result.Data = data;// EntityHelper.ConverToTEntity<RMS_Menu_Extend>(data);
            }
            result.IsSuccess = true;
            return result;
        }
        /// <summary>
        /// 根据管理员Id和项目Id获取菜单列表
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="programId">项目Id</param>
        /// <returns></returns>
        public virtual CommonOutPutVm GetMenuByManagerId(string userId, string programId)
        {
            var result = new CommonOutPutVm();
            using (var db = new RMSEntities())
            {
                string sql = @"
select m.* from RMS_Menu m 
left join RMS_Program p on m.ProgramId=p.Id and p.Deleted=0 and p.[Status]=1
join (
select distinct rm.MenuId from RMS_Role_Menu rm 
left join RMS_Role r on r.Id=rm.RoleId and r.Deleted=0 and r.[Status]=1
left join RMS_User_Role ur on ur.RoleId=r.Id and ur.Deleted=0
left join RMS_User u on u.Id=ur.UserId and u.Deleted=0 and u.[Status]=1
where rm.Deleted=0 and u.Id=@userId
) t on t.MenuId=m.Id
where m.Deleted=0 and m.[Status]=1 and p.Id=@programId
order by m.Ordering
";
                var data = db.Database.SqlQuery<RMS_Menu>(sql
                    , new SqlParameter("@userId", userId)
                    , new SqlParameter("@programId", programId)).ToList();
                result.Data = data;
            }
            result.IsSuccess = true;
            return result;
        }

        /// <summary>
        /// 级联删除
        /// </summary>
        /// <param name="id">Id串</param>
        /// <param name="db">数据实体</param>
        /// <returns></returns>
        private CommonOutPutVm DeleteSon(string id, RMSEntities db)
        {
            CommonOutPutVm result = new CommonOutPutVm();
            var sons = db.Database.SqlQuery<RMS_Menu>("select * from RMS_Menu where Deleted=0 and ParentId in ('" + id + "')").ToList();
            if (sons.Count > 0)
            {
                List<string> sonsids = (from s in sons select s.Id).ToList();
                string sonsidstr = string.Join("','", sonsids);
                result = DeleteSon(sonsidstr, db);
                if (result.IsSuccess)
                {
                    db.Database.ExecuteSqlCommand("update RMS_Menu set Deleted=1 where Deleted=0 and ParentId in ('" + id + "')");
                    db.SaveChanges();
                }
            }
            result.IsSuccess = true;
            return result;
        }
        /// <summary>
        /// 级联禁用
        /// </summary>
        /// <param name="id">Id串</param>
        /// <param name="db">数据实体</param>
        /// <returns></returns>
        private CommonOutPutVm DisableSon(string id, RMSEntities db)
        {
            CommonOutPutVm result = new CommonOutPutVm();
            var sons = db.Database.SqlQuery<RMS_Menu>("select * from RMS_Menu where Deleted=0 and [Status]=1 and ParentId in ('" + id + "')").ToList();
            if (sons.Count > 0)
            {
                List<string> sonsids = (from s in sons select s.Id).ToList();
                string sonsidstr = string.Join("','", sonsids);
                result = DisableSon(sonsidstr, db);
                if (result.IsSuccess)
                {
                    db.Database.ExecuteSqlCommand("update RMS_Menu set [Status]=0 where Deleted=0 and [Status]=1 and ParentId in ('" + id + "')");
                    db.SaveChanges();
                }
            }
            result.IsSuccess = true;
            return result;
        }
        /// <summary>
        /// 级联起用
        /// </summary>
        /// <param name="parentId">父级Id</param>
        /// <param name="db">数据实体</param>
        /// <returns></returns>
        private CommonOutPutVm EnableSon(string parentId, RMSEntities db)
        {
            CommonOutPutVm result = new CommonOutPutVm();
            var parent = db.RMS_Menu.AsNoTracking().FirstOrDefault(p => p.Id == parentId);
            if (parent!=null)
            {
                result = EnableSon(parent.ParentId, db);
                if (result.IsSuccess && parent.Status != (int)E_Status.Enable)
                {
                    db.Entry(parent).State = EntityState.Unchanged;
                    parent.Status = (int)E_Status.Enable;
                    db.Entry(parent).Property(p => p.Status).IsModified = true;
                    db.SaveChanges();
                }
            }
            result.IsSuccess = true;
            return result;
        }
    }
}
